/**
 * @author haina.z@163.com
 * @brief test crc functions
 * @version V1.0
 */

/** Includes -----------------------------------------------------------------*/
#include "public_defs.h"
#include "crc\crc8.h"
#include "crc\crc16.h"
#include "crc\crc32.h"
#include "test_crc.h"

/** Macros and constants -----------------------------------------------------*/

/** Type definitions ---------------------------------------------------------*/

/** Private variable definitions (static) ------------------------------------*/
static const uint8_t trBuffer1[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};

/** Static function declarations (prototypes) --------------------------------*/
static void TestCrc_privCrc8(const uint8_t *pBuf, uint16_t u16Len);
static void TestCrc_privCrc16(const uint8_t *pBuf, uint16_t u16Len);
static void TestCrc_privCrc32(const uint8_t *pBuf, uint16_t u16Len);

/** Public variable definitions ----------------------------------------------*/

/** Macros (#define) ---------------------------------------------------------*/

/** Pre-compile check --------------------------------------------------------*/

/** Code ---------------------------------------------------------------------*/

void TestCrc_Perform(void)
{
    TestCrc_privCrc8(trBuffer1, sizeof(trBuffer1));
    TestCrc_privCrc16(trBuffer1, sizeof(trBuffer1));
    TestCrc_privCrc32(trBuffer1, sizeof(trBuffer1));
}

static void TestCrc_privCrc8(const uint8_t *pBuf, uint16_t u16Len)
{
    uint8_t u8Crc1, u8Crc2;
    uint16_t u16Cnt;

    // 直接计算CRC8
    u8Crc1 = CRC8_CalculateWithPoly(pBuf, u16Len);
    u8Crc2 = CRC8_CalculateWithTable(pBuf, u16Len);

    printf("Crc original data (hex): ");
    for (u16Cnt = 0; u16Cnt < u16Len; u16Cnt++ )
    {
        printf("%X ", trBuffer1[u16Cnt]);
    }
    printf("-> 0x%X 0x%X\n\n", u8Crc1, u8Crc2);

    // 初始化CRC值
    CRC8_Init(&u8Crc1);
    CRC8_Init(&u8Crc2);

    // 按字节逐步计算CRC
    for (u16Cnt = 0; u16Cnt < u16Len; u16Cnt++ )
    {
        CRC8_UpdateWithPoly(&u8Crc1, trBuffer1[u16Cnt]);
        CRC8_UpdateWithTable(&u8Crc2, trBuffer1[u16Cnt]);
    }

    printf("CRC8 -> 0x%X 0x%X\n\n", u8Crc1, u8Crc2);
}

static void TestCrc_privCrc16(const uint8_t *pBuf, uint16_t u16Len)
{
    uint16_t u16Crc1, u16Crc2;

    // 计算 CRC16/Modbus
    u16Crc1 = CRC16Modbus_CalculateWithPoly(pBuf, u16Len);
    u16Crc2 = CRC16Modbus_CalculateWithTable(pBuf, u16Len);
    printf("CRC16 Modbus -> 0x%X 0x%X\n\n", u16Crc1, u16Crc2);

    // 计算 CRC16/XMODEM
    u16Crc1 = CRC16XModem_CalculateWithPoly(pBuf, u16Len);
    u16Crc2 = CRC16XModem_CalculateWithTable(pBuf, u16Len);
    printf("CRC16 XModem -> 0x%X 0x%X\n\n", u16Crc1, u16Crc2);
}

static void TestCrc_privCrc32(const uint8_t *pBuf, uint16_t u16Len)
{
    uint32_t u32Crc1;

    // 计算 CRC32
    CRC32_Init(CRC32_ETHERNET_POLY);
    u32Crc1 = mCRC32_EthernetCalculate(pBuf, u16Len);

    printf("CRC32 -> 0x%X\n\n", u32Crc1);
}

/******************************** End of file *********************************/
